package com.james.codeauto.util;

import com.james.codeauto.common.StringUtils;
import com.james.codeauto.tools.json.JSONArray;
import com.james.codeauto.tools.json.JSONObject;
import org.apache.poi.ooxml.POIXMLDocument;
import org.apache.poi.ooxml.extractor.POIXMLTextExtractor;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
import org.apache.poi.xwpf.usermodel.IBodyElement;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;

/**
 * @Author：hp
 * @Description：
 * @Date：2021年11月4日14:58:11
 * @Modified by：读取word所有内容
 **/
public class ParkingLotInnerDocUtil {
    public static void main(String[] args) {
        try {
            parseHtmlData();
        } catch (Exception e) {
            e.printStackTrace();
        }
        // String content = readWord(parseDocFromGreenCloudPath());
        // System.out.println(content);
    }

    public static List<Map<String, Object>> parseHtmlData() throws Exception {
        HashSet<String> paramKeyTypes = new HashSet<>();
        List<Map<String, Object>> listData = new ArrayList<>();
        FileInputStream fileOutputStream = new FileInputStream(parseHtmlFromGreenCloudPath());
        String htmlText = new String(fileOutputStream.readAllBytes());
        fileOutputStream.close();
        Document doc = Jsoup.parse(htmlText);
        Elements h2Element = doc.getElementsByTag("h1");

        for (int i = h2Element.size() - 1; i >= 0; i--) {
            if (!h2Element.get(i).attr("style").equals("mso-pagination:widow-orphan;")) {
                h2Element.remove(i);
            }
        }

        h2Element.remove(1);
        h2Element.remove(0);
        System.out.println(h2Element.size());
        Elements childE = doc.getElementsByClass("Section0").first().children();
        Elements pNewElement = new Elements();
        for (int i = 0; i < childE.size(); i++) {
            String p = childE.get(i).attr("class");
            if (StringUtils.isNotBlank(p) && p.equals("MsoNormal")) {

                pNewElement.add(childE.get(i));
            }
        }
        for (int i = 7; i >= 0; i--) {
            pNewElement.remove(i);
        }
        int size = pNewElement.size() / 5;
        System.out.println(size + "");//3个一组

        Elements tbodyElement = doc.getElementsByTag("tbody");
        tbodyElement.remove(0);
        //第9个插入
        tbodyElement.add(tbodyElement.size() - 1, new Element("Empty"));

        //章节4-8 共5个table response 为返回2个需合并，需要重新组合
        for (int i = 0; i < 3; i++) {
            tbodyElement.add(5 * i + 3, new Element("Empty"));
        }
        int tbodyElementSize = tbodyElement.size() / 5;
        System.out.println(tbodyElementSize + "");//5个一组

        for (int i = 0; i < h2Element.size(); i++) {
            Map<String, Object> parseMap = new HashMap<>();
            String title = h2Element.get(i).text();
            parseMap.put("title", title.substring(title.indexOf("、") + 1).trim());
            //method ->  测试环境： https://acscloudtest.parking24.cn/open_platform/portal/outer/get_park_info
            int descIndex = i * 5, urlIndex = i * 5 + 2;
//
            if (descIndex >= pNewElement.size()) {
                continue;
            }
            parseMap.put("desc", pNewElement.get(descIndex).text().replace("·", "").trim());
            parseMap.put("url", pNewElement.get(urlIndex).text().replace("·", "").replace("测试环境： ", "").trim().replace("测试环境: ", "").trim().replace("http://192.168.xx.xx:port", ""));
            parseMap.put("url", parseMap.get("url").toString().substring(0, parseMap.get("url").toString().length() - 1));
            parseMap.put("method", "POST");


            Elements table1Element = tbodyElement.get(5 * i).getElementsByTag("tr");
            JSONArray paramInfo = new JSONArray();
            for (int j = 0; j < table1Element.size(); j++) {
                Elements table1TdElement = table1Element.get(j).getElementsByTag("td");
                JSONObject jsonObjectParam = new JSONObject();
                for (int k = 0; k < table1TdElement.size(); k++) {
                    Element td = table1TdElement.get(k);
                    String paramStr = td.text();
                    if (k == 0) {
                        //参数名

                        jsonObjectParam.put("name", paramStr.trim());
                        jsonObjectParam.put("realName", paramStr.trim());
                    } else if (k == 1) {
                        //必选
                        jsonObjectParam.put("require", paramStr.trim());

                    } else if (k == 2) {

                        paramKeyTypes.add(paramStr);
                        //默认值
                        jsonObjectParam.put("type", paramStr);
                    } else if (k == 3) {
                        //说明
                        jsonObjectParam.put("desc", paramStr);
                        jsonObjectParam.put("defaultValue", "");
                        jsonObjectParam.put("descMore", "");
                    }

                    System.out.println(paramStr);
                }
                if (jsonObjectParam.get("name").toString().contains("参数名")) {
                    continue;
                }
                if (jsonObjectParam.get("name").toString().contains("utc_timestamp")) {
                    continue;
                }
                if (jsonObjectParam.get("name").toString().equals("sign")) {
                    continue;
                }

                if (jsonObjectParam.get("name").toString().contains("名称")) {
                    continue;
                }

                jsonObjectParam.put("treeNode", "0");
                String reuqire = (String) jsonObjectParam.get("require");
                String type = (String) jsonObjectParam.get("type");
                if ("是".equals(reuqire) || "否".equals(reuqire)) {

                } else {
                    jsonObjectParam.put("type", reuqire);
                    jsonObjectParam.put("require", type);
                }
                paramInfo.put(jsonObjectParam);
            }
            parseMap.put("paramList", paramInfo);
            Elements table2Element = tbodyElement.get(5 * i + 2).getElementsByTag("tr");
            String tagName = tbodyElement.get(5 * i + 3).tagName();
            if (!"Empty".equals(tagName)) {
                Elements table3Element = tbodyElement.get(5 * i + 3).getElementsByTag("tr");

                if (table3Element != null && table3Element.size() > 0) {
                    table2Element.addAll(table3Element);
                }
            }

            JSONArray responseParamInfo = new JSONArray();

            for (int j = 0; j < table2Element.size(); j++) {
                Elements table2TdElement = table2Element.get(j).getElementsByTag("td");

                JSONObject jsonObjectParam = new JSONObject();
                int len = table2TdElement.size();
                for (int k = 0; k < len; k++) {
                    Element td = table2TdElement.get(k);

                    String responseParamStr = td.text();
                    System.out.println(responseParamStr);
                    if (k == 0) {
                        //参数名

                        jsonObjectParam.put("name", responseParamStr.trim());
                        jsonObjectParam.put("realName", responseParamStr.trim());
                    } else if (k == 1) {
                        //必选
                        jsonObjectParam.put("require", responseParamStr.trim());

                    } else if (k == 2) {

                        paramKeyTypes.add(responseParamStr);
                        //默认值
                        jsonObjectParam.put("type", responseParamStr.trim());
                    } else if (k == 3) {
                        //说明
                        jsonObjectParam.put("desc", responseParamStr);
                        jsonObjectParam.put("defaultValue", "");
                        jsonObjectParam.put("descMore", "");
                    }
                    System.out.println(responseParamStr);
                }
                if (jsonObjectParam.get("name").toString().contains("参数名")) {
                    continue;
                }
                if (jsonObjectParam.get("name").toString().contains("名称")) {
                    continue;
                }
                jsonObjectParam.put("treeNode", "0");
                String reuqire = (String) jsonObjectParam.get("require");
                String type = (String) jsonObjectParam.get("type");
                if ("是".equals(reuqire) || "否".equals(reuqire)) {

                } else {
                    jsonObjectParam.put("type", reuqire);
                    jsonObjectParam.put("require", type);
                }
                responseParamInfo.put(jsonObjectParam);

            }
            parseMap.put("responseParamList", responseParamInfo);

            //构造json
            Elements table1JsonElement = tbodyElement.get(5 * i + 1).getElementsByTag("tr");

            JSONObject jsonParamObject = convertListParamToJsonObj(parseMap, table1JsonElement);
            parseMap.put("paramJson", jsonParamObject);
            parseMap.put("paramJsonStr", jsonParamObject.toString(4));
            Elements table2JsonElement = tbodyElement.get(5 * i + 4).getElementsByTag("tr");

            JSONObject responseJsonParamObject = convertListParamToJsonObj(parseMap, table2JsonElement);
            parseMap.put("responseJson", responseJsonParamObject);
            parseMap.put("responseParamJsonStr", responseJsonParamObject.toString(4));

            JSONObject response = (JSONObject) parseMap.get("responseJson");
            if (response.opt("data") != null) {
                if (StringUtils.isNotBlank(response.optString("page_size"))) {
                    parseMap.put("hasPage", "true");
                }
                if (response.get("data") instanceof JSONArray) {
                    parseMap.put("responseJson", response.optJSONArray("data"));
                } else {
                    parseMap.put("responseJson", response.optJSONObject("data"));
                }
            }

            if (response.opt("car_park_info") != null) {
                parseMap.put("responseJson", response.optJSONObject("car_park_info"));
            }
            if (response.opt("parking_info_list") != null) {
                parseMap.put("responseJson", response.optJSONObject("parking_info_list"));
            }

            if (response.opt("area_info") != null) {
                parseMap.put("responseJson", response.optJSONArray("area_info"));
            }

            JSONObject paramJson = (JSONObject) parseMap.get("paramJson");
            if (paramJson.opt("data") != null) {
                if (paramJson.get("data") instanceof JSONArray) {
                    parseMap.put("paramJson", paramJson.optJSONArray("data"));
                } else {
                    parseMap.put("paramJson", paramJson.optJSONObject("data"));
                }
            }


            String reqJsonCommentStr = "";
            for (int j = 0; j < paramInfo.length(); j++) {
                JSONObject reqParamObject = paramInfo.getJSONObject(j);
                String desc = reqParamObject.optString("desc");
                if (!StringUtils.isNotBlank(desc)) {
                    desc = reqParamObject.getString("name");
                }
                reqJsonCommentStr += reqParamObject.getString("name") + "\t";
                reqJsonCommentStr += desc + "\t";
                reqJsonCommentStr += reqParamObject.optString("type") + "\t";
                reqJsonCommentStr += reqParamObject.optString("require") + "\t";
                reqJsonCommentStr += "" + "\t";
                reqJsonCommentStr += desc + "\n";

            }
            parseMap.put("reqJsonCommentStr", reqJsonCommentStr);

            String jsonCommentStr = "";
            for (int j = 0; j < responseParamInfo.length(); j++) {
                JSONObject responseParamObject = responseParamInfo.getJSONObject(j);
                String desc = responseParamObject.optString("desc");
                if (!StringUtils.isNotBlank(desc)) {
                    desc = responseParamObject.getString("name");
                }
                jsonCommentStr += responseParamObject.getString("name") + "\t";
                jsonCommentStr += desc + "\t";
                jsonCommentStr += responseParamObject.optString("type") + "\t";
                jsonCommentStr += responseParamObject.optString("require") + "\t";
                jsonCommentStr += "" + "\t";
                jsonCommentStr += desc + "\n";

            }
            parseMap.put("jsonCommentStr", jsonCommentStr);

            checkSaveMarkdownToFile(parseMap);


            listData.add(parseMap);
        }

        System.out.println("paramKeyTypes===" + paramKeyTypes.toString());
        return listData;
    }

    private static int currentIndex = 0;

    //number, boolean, string, integer, object, object [], string [],
    public static JSONObject convertListParamToJsonObj(Map<String, Object> parseMap, Elements jsonEle) {

        String info = jsonEle.text().trim();
        try {
            if (parseMap.get("url").toString().contains("get_plate_no_info")) {
                info = info.replace("\"parking_lot_no\": \"A001\"", "\"parking_lot_no\": \"A001\",");
            }
            if (parseMap.get("url").toString().contains("get_parking_info")) {
                info = info.replace("\"parking_space_no\": \"A001\"", "\"parking_space_no\": \"A001\",");
                info = info.replace("\"parking_space_no\": \"A002\"", "\"parking_space_no\": \"A002\",");
            }


            JSONObject jsonObject = new JSONObject(info);
            return jsonObject;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private static JSONObject parseParam(JSONArray paramInfo, JSONObject paramObj, JSONObject jsonObject, int currentNode) {
        String name = paramObj.optString("name").trim();
        if (StringUtils.isNotBlank(name)) {
            String type = paramObj.optString("type");
            if (type.equals("number")) {
                jsonObject.put(name, 1.0);
            } else if (type.equals("integer")) {
                jsonObject.put(name, 1);
            } else if (type.equals("boolean")) {
                jsonObject.put(name, true);
            } else if (type.equals("string []")) {
                JSONArray childObjArray = new JSONArray();
                childObjArray.put("String");
                jsonObject.put(name, childObjArray);
            } else if (type.equals("object")) {
                JSONObject childObj = new JSONObject();
                //treeNodeCheck
                currentIndex++;
                childObj = parseParam(paramInfo, paramInfo.getJSONObject(currentIndex), childObj, Integer.parseInt(paramObj.getString("treeNode")) + 1);
                jsonObject.put(name, childObj);
            } else if (type.equals("object []")) {
                JSONArray childObjArray = new JSONArray();
                //treeNodeCheck
                currentIndex++;
                for (int i = 0; i < 1; i++) {
                    JSONObject childObj = new JSONObject();
                    childObj = parseParam(paramInfo, paramInfo.getJSONObject(currentIndex), childObj, Integer.parseInt(paramObj.getString("treeNode")) + 1);
                    childObjArray.put(childObj);
                }
                jsonObject.put(name, childObjArray);
            } else if (type.equals("string")) {
                String defaultValue = paramObj.optString("defaultValue");
                if (StringUtils.isNotBlank(defaultValue)) {
                    jsonObject.put(name, defaultValue);
                } else {
                    jsonObject.put(name, "String");
                }

            }

            if (currentNode == Integer.parseInt(paramObj.getString("treeNode"))) {
                //in sub node
                if (paramInfo.length() > currentIndex + 1) {
                    JSONObject paramCheck = paramInfo.getJSONObject(currentIndex + 1);
                    if (currentNode == Integer.parseInt(paramCheck.getString("treeNode"))) {
                        //still the same
                        currentIndex++;
                        jsonObject = parseParam(paramInfo, paramCheck, jsonObject, Integer.parseInt(paramObj.getString("treeNode")));
                    }


                }

            }
        }
        return jsonObject;
    }

    static boolean saveMarkDownFile = false;

    private static void checkSaveMarkdownToFile(Map<String, Object> parseMap) throws Exception {
        if (saveMarkDownFile) {
            String title = (String) parseMap.get("title");
            String fileName = title.replaceAll("/", "-") + ".md";
            // 从JDK1.7开始提供的方法
            // 使用Files.write创建一个文件并写入
            try {
                Files.write(Paths.get(fileName), GenMarkDownUtils.generatorCode(parseMap).getBytes(StandardCharsets.UTF_8));
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

    public static String parseHtmlFromGreenCloudPath() {
        String html = "场内标准接口V1.0.3.html";
        String path = Paths.get("doc", html).toAbsolutePath().toString();
        return path;
    }

    public static String parseDocFromGreenCloudPath() {
        String html = "绿云会员接口手册.docx";
        String path = Paths.get("doc", html).toAbsolutePath().toString();
        return path;
    }

    public static String processParagraphs(XWPFParagraph paragraph, XWPFDocument doc) {

        List<XWPFRun> runs = paragraph.getRuns();
        String paragraphText = "";
        for (XWPFRun run : runs) {
            String text = run.getText(0);                                                                       //分段是poi来完成的,但是它分段的时候可能出现${CJ_CP}${CL_LX}这种情况
            System.out.println("text---->" + text);
            if (text != null) {
                paragraphText += text;
            }
        }
        System.out.println("@@@@=" + paragraphText);
        return paragraphText;
    }

    public static String readWord(String path) {
        String buffer = "";
        try {
            if (path.endsWith(".docx")) {
                InputStream is2 = new FileInputStream(new File(path));
                XWPFDocument docx = new XWPFDocument(is2);
                for (int i = 0; i < docx.getBodyElements().size(); i++) {
                    IBodyElement element = docx.getBodyElements().get(i);
                    if (element instanceof XWPFParagraph) {
                        XWPFParagraph xwpfParagraph = (XWPFParagraph) element;
                        processParagraphs(xwpfParagraph, docx);
                    } else {
                        //table.

                    }
                }
                int tables = docx.getTables().size();
                System.out.println(tables);
                docx.close();

                OPCPackage opcPackage = POIXMLDocument.openPackage(path);
                POIXMLTextExtractor extractor = new XWPFWordExtractor(opcPackage);
                buffer = extractor.getText();
                extractor.close();
            }
//            else if (path.endsWith("docx")) {
//                OPCPackage opcPackage = POIXMLDocument.openPackage(path);
//                POIXMLTextExtractor extractor = new XWPFWordExtractor(opcPackage);
//                buffer = extractor.getText();
//                extractor.close();
//            }
            else {
                System.out.println("此文件不是word文件！");
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return buffer;
    }
}
